package demo17

import "fmt"

// 职责链设计模式

// 吃饭--》嘴--->胃0---》肠道
// 设计分析: 所有一个流程都有消化动作和 前提条件是否吃饱的设计【这里就用嘴的饭量能接受多少来表示】
//

// 抽象出来的接口
type Manager interface {
	Hunger(food int) bool   // 饥饿度
	Digestibility(food int) // 是否饥饿
}

// 抽象出来的实例对象
type OrganChain struct {
	Manager
	successor *OrganChain
}

// 抽离的调用方法 建立衔接关系
func (o *OrganChain) SetSuccessor(orgn *OrganChain) {
	o.successor = orgn
}

// 每个位置的几个度，是否满足如果满足的就继续消化
// 如果当前位置食物消化完了就结束
func (o *OrganChain) Hunger(food int) bool {
	// 这里仅仅是个模板
	return true
}

// 衔接逻辑
func (o *OrganChain) Digestibility(food int) {
	// false就是 没有消化完

	if o.Manager.Hunger(food) {
		// 消化完了
		o.Manager.Digestibility(food)
		return
	}
	// 判断是否还有其他位置需要进行吸收消化，这个里的作用就是让身体增加肥肉，如果一直迭代消化下去
	if o.successor != nil {
		o.successor.Digestibility(food)
	} else {
		fmt.Printf("一次吃了:%d,未消化:%d, 吃的非常多了\n", food, food)
	}
	// fmt.Printf("一次吃了:%d,未消化:%d, 吃的非常多了\n", food, food)
}

type Mouth struct{}

func NewMouth() *OrganChain {
	return &OrganChain{
		Manager: &Mouth{},
	}
}

func (m *Mouth) Hunger(food int) bool {
	// 嘴消化每次食物都比较小那么定位小一点
	// 消化的话可以一直消化，
	return food < 200
}

func (m *Mouth) Digestibility(food int) {
	fmt.Println("嘴吃了食物:", food)
	// 嘴是否能够吃那么多
	if food <= 100 {
		fmt.Printf("一次吃了:%d,消化了:%d\n", food, food)
		return
	}
	fmt.Printf("一次吃了:%d,未消化:%d, 但是吃多了\n", food, food-100)
}

// 这个案例举例不是很好。因为可以选择不同的位置去消化不同级别的食物，比如嘴消化不了大于200的食物
// 那么可以让胃去消化，这个就是超能力选择部位去消化

// 胃
type Stomach struct{}

func NewStomach() *OrganChain {
	return &OrganChain{
		Manager: &Stomach{},
	}
}

func (s *Stomach) Hunger(food int) bool {
	return food < 500
}

func (s *Stomach) Digestibility(food int) {
	fmt.Println("胃得到食物:", food)

	if food <= 400 {
		fmt.Printf("一次吃了:%d,消化了:%d\n", food, food)
		return
	}
	fmt.Printf("一次吃了:%d,未消化:%d, 但是吃多了\n", food, food-400)

}
